#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
匹配规则配置模型 - 存储匹配算法的规则配置
"""

from app import db
from datetime import datetime
import json


class MatchingRule(db.Model):
    """匹配规则配置表"""
    __tablename__ = 'matching_rules'
    
    id = db.Column(db.Integer, primary_key=True, comment='主键ID')
    rule_code = db.Column(db.String(50), unique=True, nullable=False, comment='规则编码')
    rule_name = db.Column(db.String(100), nullable=False, comment='规则名称')
    rule_type = db.Column(db.String(20), nullable=False, comment='规则类型：weight/threshold/mapping')
    category = db.Column(db.String(30), nullable=False, comment='规则分类：age/education/income等')
    rule_config = db.Column(db.Text, comment='规则配置JSON')
    weight = db.Column(db.Float, default=1.0, comment='权重')
    is_active = db.Column(db.Boolean, default=True, comment='是否启用')
    sort_order = db.Column(db.Integer, default=0, comment='排序')
    description = db.Column(db.Text, comment='规则描述')
    create_time = db.Column(db.DateTime, default=datetime.now, comment='创建时间')
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    
    def to_dict(self):
        """转换为字典格式"""
        data = {
            'id': self.id,
            'rule_code': self.rule_code,
            'rule_name': self.rule_name,
            'rule_type': self.rule_type,
            'category': self.category,
            'rule_config': self.get_rule_config(),
            'weight': self.weight,
            'is_active': self.is_active,
            'sort_order': self.sort_order,
            'description': self.description,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'update_time': self.update_time.strftime('%Y-%m-%d %H:%M:%S') if self.update_time else None
        }
        return data
    
    def get_rule_config(self):
        """获取规则配置（解析JSON）"""
        if self.rule_config:
            try:
                return json.loads(self.rule_config)
            except (json.JSONDecodeError, TypeError):
                return {}
        return {}
    
    def set_rule_config(self, config_dict):
        """设置规则配置（转换为JSON）"""
        if config_dict:
            self.rule_config = json.dumps(config_dict, ensure_ascii=False)
        else:
            self.rule_config = None
    
    @classmethod
    def get_rules_by_category(cls, category):
        """根据分类获取规则列表"""
        return cls.query.filter_by(category=category, is_active=True)\
                       .order_by(cls.sort_order, cls.id)\
                       .all()
    
    @classmethod
    def get_rule_by_code(cls, rule_code):
        """根据规则编码获取规则"""
        return cls.query.filter_by(rule_code=rule_code, is_active=True).first()
    
    @classmethod
    def get_weight_rules(cls):
        """获取所有权重规则"""
        return cls.query.filter_by(rule_type='weight', is_active=True)\
                       .order_by(cls.sort_order, cls.id)\
                       .all()
    
    @classmethod
    def get_threshold_rules(cls):
        """获取所有阈值规则"""
        return cls.query.filter_by(rule_type='threshold', is_active=True)\
                       .order_by(cls.sort_order, cls.id)\
                       .all()
    
    @classmethod
    def get_mapping_rules(cls):
        """获取所有映射规则"""
        return cls.query.filter_by(rule_type='mapping', is_active=True)\
                       .order_by(cls.sort_order, cls.id)\
                       .all()


class MatchingScore(db.Model):
    """匹配评分记录表"""
    __tablename__ = 'matching_scores'
    
    id = db.Column(db.Integer, primary_key=True, comment='主键ID')
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, comment='用户ID')
    target_user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, comment='目标用户ID')
    total_score = db.Column(db.Float, nullable=False, comment='总分')
    match_percentage = db.Column(db.Float, nullable=False, comment='匹配百分比')
    score_details = db.Column(db.Text, comment='评分详情JSON')
    algorithm_version = db.Column(db.String(20), default='v1.0', comment='算法版本')
    is_valid = db.Column(db.Boolean, default=True, comment='是否有效')
    create_time = db.Column(db.DateTime, default=datetime.now, comment='创建时间')
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    
    # 添加外键关系
    user = db.relationship('User', foreign_keys=[user_id], backref='sent_matches')
    target_user = db.relationship('User', foreign_keys=[target_user_id], backref='received_matches')
    
    # 创建复合索引
    __table_args__ = (
        db.Index('idx_user_target', 'user_id', 'target_user_id'),
        db.Index('idx_match_percentage', 'match_percentage'),
        db.Index('idx_create_time', 'create_time'),
    )
    
    def to_dict(self):
        """转换为字典格式"""
        data = {
            'id': self.id,
            'user_id': self.user_id,
            'target_user_id': self.target_user_id,
            'total_score': self.total_score,
            'match_percentage': self.match_percentage,
            'score_details': self.get_score_details(),
            'algorithm_version': self.algorithm_version,
            'is_valid': self.is_valid,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'update_time': self.update_time.strftime('%Y-%m-%d %H:%M:%S') if self.update_time else None
        }
        return data
    
    def get_score_details(self):
        """获取评分详情（解析JSON）"""
        if self.score_details:
            try:
                return json.loads(self.score_details)
            except (json.JSONDecodeError, TypeError):
                return {}
        return {}
    
    def set_score_details(self, details_dict):
        """设置评分详情（转换为JSON）"""
        if details_dict:
            self.score_details = json.dumps(details_dict, ensure_ascii=False)
        else:
            self.score_details = None
    
    @classmethod
    def get_user_matches(cls, user_id, min_percentage=0, limit=50):
        """获取用户的匹配记录"""
        return cls.query.filter(
            cls.user_id == user_id,
            cls.is_valid == True,
            cls.match_percentage >= min_percentage
        ).order_by(cls.match_percentage.desc(), cls.create_time.desc())\
         .limit(limit).all()
    
    @classmethod
    def get_match_score(cls, user_id, target_user_id):
        """获取两个用户之间的匹配分数"""
        return cls.query.filter_by(
            user_id=user_id,
            target_user_id=target_user_id,
            is_valid=True
        ).order_by(cls.create_time.desc()).first()
    
    @classmethod
    def get_high_matches(cls, min_percentage=80, limit=100):
        """获取高匹配度的记录"""
        return cls.query.filter(
            cls.is_valid == True,
            cls.match_percentage >= min_percentage
        ).order_by(cls.match_percentage.desc(), cls.create_time.desc())\
         .limit(limit).all() 